package top.mindse.office2pdf.aspect;

import cn.hutool.json.JSONUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import top.mindse.office2pdf.entity.UserDemo;

import java.lang.reflect.Method;

@Aspect
@Component
public class LogRecordAspect {
    private final Logger log = LoggerFactory.getLogger(LogRecordAspect.class);

    @Pointcut("@annotation(top.mindse.office2pdf.aspect.LogRecord)")
    public void controllerLog() {
    }

    @Around("controllerLog()")
    public Object doAround(ProceedingJoinPoint pjp) throws Exception {
        UserDemo args = (UserDemo) pjp.getArgs()[0];
        Method method = getMethod(pjp);
        String desc = method.getAnnotation(LogRecord.class).desc();

        StandardEvaluationContext context = new StandardEvaluationContext();
        Method deveryUser = UserDemo.class.getDeclaredMethod("deveryUser", String.class);
        context.registerFunction("deveryUser", deveryUser);
        context.setVariable("request", args);
        ExpressionParser parser = new SpelExpressionParser();
        log.info(JSONUtil.toJsonStr(parser.parseExpression(desc).getValue(context)));

        //获取结果，影响 Response 的值
        try {
            Object result = pjp.proceed();
            System.out.println(JSONUtil.toJsonStr(result));
            return result;
        } catch (Throwable throwable) {
            log.error("执行方法异常", throwable);
            Class<?> returnType = method.getReturnType();
            Object result = returnType.getDeclaredConstructor().newInstance();
            return result;
        }
    }

    protected Method getMethod(JoinPoint joinPoint) {
        Method method = null;
        try {
            Signature signature = joinPoint.getSignature();
            MethodSignature ms = (MethodSignature) signature;
            Object target = joinPoint.getTarget();
            method = target.getClass().getMethod(ms.getName(), ms.getParameterTypes());
        } catch (Exception e) {
            log.error("获取方法错误", e);
        }
        return method;
    }
}
